using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using sqengine.Engine.Common;
using SqEngine;


namespace sqengine.Components
{

    public class PresentationArgs : System.EventArgs
    {

        private string message;

        public PresentationArgs(string m)
        {
            this.message = m;
        }

        public string Message()
        {
            return message;
        }

    }

    public class PresentationSystem : Microsoft.Xna.Framework.DrawableGameComponent
    {
        private AdvancedContent _adcontent;
        private bool _active = false;
        private List<PresentationMessage> _queue = new List<PresentationMessage>();

        public delegate void ChangingHandler(object sender, PresentationArgs ca);

        // event declaration
        public event ChangingHandler OnStateChange;


        private SpriteBatch _spritebatch;
        private SpriteFont _drw_font;
        Game _game;
        private double tmpfade = 0;
        private double tmplife = 0;
        private int tmpalpha = 0;
        private string s_typewrite = "";
        private int idx_typ = 0;

        public PresentationSystem(Game game, AdvancedContent adcontent)
            : base(game)
        {
            _adcontent = adcontent;

            _game = game;
        }


        public override void Initialize()
        {
            base.Initialize();
        }

        public override void Update(GameTime gameTime)
        {
            KeyboardState kb = Keyboard.GetState();

            //Press SPACE to skip
            if (kb.IsKeyDown(Keys.Space))
            {
                Stop();
                ClearQueue();
            }


            if (_active)
            {
                if (_queue.Count > 0)
                {
                    //Fade in
                    if (_queue[0].state == 0)
                    {
                        if (tmpfade <= 0)
                        {

                            tmpfade = _queue[0].fade_time;
                            _queue[0].state = 1;
                        }
                        else
                        {
                            tmpfade -= gameTime.ElapsedGameTime.TotalMilliseconds;
                            _queue[0].alpha += System.Convert.ToInt32(_queue[0].fade_time / 255);
                            tmpalpha = _queue[0].alpha;

                        }

                    }

                    // Stay on screen
                    if (_queue[0].state == 1)
                    {
                        if (tmplife <= 0)
                        {
                            _queue[0].state = 2;
                        }
                        else
                        {
                            tmplife -= gameTime.ElapsedGameTime.TotalMilliseconds;
                            _queue[0].alpha = 255;
                            tmpalpha = _queue[0].alpha;
                        }

                    }

                    //Fade out
                    if (_queue[0].state == 2)
                    {

                        if (tmpfade <= 0)
                        {

                            tmpfade = _queue[0].fade_time;
                            tmplife = _queue[0].lifetime;
                            _queue[0].state = -1;

                            _queue.RemoveAt(0);

                            if (_queue.Count == 0)
                            {
                                Stop();



                            }
                        }
                        else
                        {
                            tmpfade -= gameTime.ElapsedGameTime.TotalMilliseconds;
                            _queue[0].alpha -= System.Convert.ToInt32(_queue[0].fade_time / 255);
                            tmpalpha = _queue[0].alpha;

                        }

                    }

                }
                else
                {


                }
            }
            base.Update(gameTime);
        }


        protected override void LoadContent()
        {
            base.LoadContent();
        }

        

        public override void Draw(GameTime gameTime)
        {
            if (_active)
            {

                if (_queue.Count > 0)
                {

                     if (_queue[0].font == "" || _queue[0].font == null)
                         _drw_font = _adcontent.LoadSpriteFont("Fonts/Miramo");
                     else
                         _drw_font = _adcontent.LoadSpriteFont(_queue[0].font);

                    _game.GraphicsDevice.Clear(Color.Black);

                    byte R = _queue[0].text_color.R;
                    byte G = _queue[0].text_color.G;
                    byte B = _queue[0].text_color.B;
                    if (_spritebatch == null)
                        _spritebatch = new SpriteBatch(_game.GraphicsDevice);

                    _spritebatch.Begin(SpriteBlendMode.AlphaBlend);

                    _queue[0] = CheckAnimation(_queue[0]);
                    if (_queue[0].background)
                    {
                        byte Rt = Color.White.R;
                        byte Gt = Color.White.G;
                        byte Bt = Color.White.B;

                        _spritebatch.Draw(_adcontent.LoadTexture2D(_queue[0].backgroundtexture), new Rectangle((int)(_queue[0].backgroundpos.X), (int)(_queue[0].backgroundpos.Y), _adcontent.LoadTexture2D(_queue[0].backgroundtexture).Width, _adcontent.LoadTexture2D(_queue[0].backgroundtexture).Height), new Color(Rt, Gt, Bt, (byte)MathHelper.Clamp(_queue[0].alpha, 0, 255)));
                    }

                    if (_queue[0].shadow)
                    {
                        byte Rs = _queue[0].shadow_color.R;
                        byte Gs = _queue[0].shadow_color.G;
                        byte Bs = _queue[0].shadow_color.B;


                        _spritebatch.DrawString(_drw_font, _queue[0].text, new Vector2(_queue[0].position.X - 1, _queue[0].position.Y - 1), new Color(Rs, Gs, Bs, (byte)MathHelper.Clamp(_queue[0].alpha, 0, 255)));
                    }

                   

                    _spritebatch.DrawString(_drw_font, _queue[0].text, _queue[0].position, new Color(R, G, B, (byte)MathHelper.Clamp(_queue[0].alpha, 0, 255)));


                    _spritebatch.End();
                }
            }
            base.Draw(gameTime);
            ((sqengine)_game).RestoreRenderState();
        }

        public void Start()
        {
            _active = true;
            DrawOrder = 1;

            if (OnStateChange != null)
            {
                PresentationArgs pa = new PresentationArgs("started");
                OnStateChange(this, pa);
            }

        }

        public void Stop()
        {
            _active = false;
            DrawOrder = 500;

            if (OnStateChange != null)
            {
                PresentationArgs pa = new PresentationArgs("stopped");
                OnStateChange(this, pa);
            }

        }

        public bool Playing()
        {
            return _active;
        }

        public void AddMessage(PresentationMessage message)
        {
            message.text = ReplaceVar(message.text);
            _queue.Add(message);
            tmpfade = message.fade_time;
            tmplife = message.lifetime;
        }

        public void QuickAddMessage(string text, string font, PresentationType animationtype, double lifetime, double fade_time, Vector2 position, Color text_color, bool shadow, Color shadow_color)
        {
            PresentationMessage pmsg = new PresentationMessage();

            pmsg.text = text;
            pmsg.font = font;
            pmsg.lifetime = lifetime;
            pmsg.fade_time = fade_time;
            pmsg.position = position;
            pmsg.text_color = text_color;
            pmsg.shadow = shadow;
            pmsg.shadow_color = shadow_color;
            pmsg.animantion = animationtype;
            AddMessage(pmsg);

        }

        public void ClearQueue()
        {
            _queue.Clear();

        }

        private PresentationMessage CheckAnimation(PresentationMessage pm)
        {
            if (pm.animantion == PresentationType.MoveHorizForward)
            {
                pm.position.X += 0.1f;

            }
            if (pm.animantion == PresentationType.MoveVertBack)
            {
                pm.position.Y -= 0.1f;

            }
            if (pm.animantion == PresentationType.MoveVertFoward)
            {
                pm.position.Y += 0.1f;
            }

            if (pm.animantion == PresentationType.MoveHorizBack)
            {
                pm.position.X -= 0.1f;
            }

            return pm;

        }

        private string ReplaceVar(string text)
        {
            text = text.Replace("{projectname}", SqEngine.SqEngineInfo._name);
            text = text.Replace("{projectversion}", SqEngine.SqEngineInfo._version);

            return text;
        }






    }
}